import { defineStore } from 'pinia'
import request from '@/api/request'
import type { ApiResponse } from '@/api/types'
import { searchUsersByEmail } from '@/api/admin/admin'
import { updateUserRole as apiUpdateUserRole } from '@/api/admin/admin'
import { updateUserPermissions as apiUpdateUserPermissions } from '@/api/admin/admin'
import type { User } from '@/types/User'
export interface AdminMenuItem {
  id?: number | string
  title: string
  path: string
  icon?: string
  children?: AdminMenuItem[]
  order?: number
  hidden?: boolean
}

export interface TabView {
  title: string
  path: string
  closable?: boolean
}

export interface DashboardStats {
  users?: number
  orders?: number
  revenue?: number
  [key: string]: number | undefined
}

export const useAdminStore = defineStore('admin', {
  state: () => ({
    // 布局/UI
    sidebarCollapsed: false as boolean,
    activeMenu: '' as string,
    tabs: [] as TabView[],
    // 权限/角色/菜单
    permissions: [] as string[],
    roles: [] as string[],
    menuItems: [] as AdminMenuItem[],
    // 仪表盘数据
    dashboard: {} as DashboardStats,
    // 加载状态
    loading: {
      permissions: false,
      menu: false,
      dashboard: false,
    } as Record<string, boolean>,
  }),

  getters: {
    isAdmin: (state) => state.roles.includes('ADMIN') || state.roles.includes('SUPER_ADMIN'),
    hasPermission: (state) => (perm: string | string[]): boolean => {
      if (!perm) return true
      const need = Array.isArray(perm) ? perm : [perm]
      return need.every(p => state.permissions.includes(p))
    },
  },

  actions: {
    async searchUsersByEmail(email: string) {
      const res = await searchUsersByEmail({ email }) as ApiResponse<{ list?: User[]; user?: User } | User[] | User | null>
      const code = (res as ApiResponse<unknown>).code
      if (code !== undefined && code !== 0 && code !== 200) {
        throw new Error((res as ApiResponse<unknown>).message || '搜索用户失败')
      }
      const data = (res as any).data ?? res
      return data as unknown
    },

    async updateUserRole(payload: { id: number | string; role: User['role'] }) {
      const res = await apiUpdateUserRole(payload) as ApiResponse<{ user?: User } | User | null>
      const code = (res as ApiResponse<unknown>).code
      if (code !== undefined && code !== 0 && code !== 200) {
        throw new Error((res as ApiResponse<unknown>).message || '更新用户角色失败')
      }
      const data = (res as any).data ?? res
      return (data?.user ?? data ?? null) as User | null
    },

    async updateUserPermissions(payload: { id: number | string; permissions: string[] }) {
      const res = await apiUpdateUserPermissions(payload) as ApiResponse<{ user?: User; permissions?: string[] } | User | null>
      const code = (res as ApiResponse<unknown>).code
      if (code !== undefined && code !== 0 && code !== 200) {
        throw new Error((res as ApiResponse<unknown>).message || '更新权限失败')
      }
      const data = (res as any).data ?? res
      // 返回最新的权限数组（若后端在 user 内或单独返回）
      const perms = (data?.permissions ?? (data?.user?.permissions) ?? undefined) as string[] | undefined
      return (data?.user ?? data ?? null) as User | null
    },

    // ========== UI 状态 ==========
    toggleSidebar() {
      this.sidebarCollapsed = !this.sidebarCollapsed
    },
    setActiveMenu(path: string) {
      this.activeMenu = path
    },

    // ========== 页签 ==========
    openTab(tab: TabView) {
      if (!this.tabs.find(t => t.path === tab.path)) {
        this.tabs.push({ ...tab, closable: tab.closable ?? true })
      }
      this.activeMenu = tab.path
    },
    closeTab(path: string) {
      const idx = this.tabs.findIndex(t => t.path === path)
      if (idx >= 0) {
        this.tabs.splice(idx, 1)
        if (this.activeMenu === path) {
          const last = this.tabs[this.tabs.length - 1]
          this.activeMenu = last?.path || '/'
        }
      }
    },
    closeOtherTabs(path?: string) {
      const keep = path || this.activeMenu
      this.tabs = this.tabs.filter(t => t.path === keep || t.closable === false)
      this.activeMenu = keep
    },
    resetTabs() {
      this.tabs = this.tabs.filter(t => t.closable === false)
      if (!this.tabs.find(t => t.path === this.activeMenu)) {
        const last = this.tabs[this.tabs.length - 1]
        this.activeMenu = last?.path || '/'
      }
    },

    // ========== 权限/角色/菜单 ==========
    setPermissions(perms: string[]) {
      this.permissions = Array.from(new Set(perms || []))
    },
    setRoles(roles: string[]) {
      this.roles = Array.from(new Set(roles || []))
    },
    setMenu(items: AdminMenuItem[]) {
      const sortRec = (list: AdminMenuItem[]): AdminMenuItem[] =>
        [...(list || [])]
          .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
          .map(i => ({ ...i, children: i.children ? sortRec(i.children) : undefined }))
      this.menuItems = sortRec(items || [])
    },

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  unwrap<T = any>(res: any): T {
      if (!res) return res as T
      if (typeof res === 'object' && 'data' in res && (res.code === 0 || res.code === 200 || res.code === undefined)) {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  return (res as any).data as T
      }
      return res as T
    },

    async fetchPermissions() {
      if (this.loading.permissions) return
      this.loading.permissions = true
      try {
        const res = await request<{ list?: string[]; permissions?: string[] }>({
          url: '/admin/permissions',
          method: 'GET',
        })
        const data = this.unwrap(res)
        const perms = (data?.permissions || data?.list || []) as string[]
        this.setPermissions(perms)
      } catch {
        // ignore
      } finally {
        this.loading.permissions = false
      }
    },

    async fetchRoles() {
      try {
        const res = await request<{ list?: string[]; roles?: string[] }>({
          url: '/admin/roles',
          method: 'GET',
        })
        const data = this.unwrap(res)
        const roles = (data?.roles || data?.list || []) as string[]
        this.setRoles(roles)
      } catch {
        // ignore
      }
    },

    async fetchMenu() {
      if (this.loading.menu) return
      this.loading.menu = true
      try {
        const res = await request<AdminMenuItem[] | { list?: AdminMenuItem[]; menus?: AdminMenuItem[] }>({
          url: '/admin/menus',
          method: 'GET',
        })
        const data = this.unwrap<AdminMenuItem[] | { menus?: AdminMenuItem[]; list?: AdminMenuItem[] } | null>(res)
        const items = (Array.isArray(data) ? data : (data?.menus || data?.list || [])) as AdminMenuItem[]
        this.setMenu(items)
      } catch {
        // ignore
      } finally {
        this.loading.menu = false
      }
    },

    async fetchDashboard() {
      if (this.loading.dashboard) return
      this.loading.dashboard = true
      try {
        const res = await request<DashboardStats | { stats?: DashboardStats }>({
          url: '/admin/dashboard/stats',
          method: 'GET',
        })
        const data = this.unwrap<DashboardStats | { stats?: DashboardStats } | null>(res)
        this.dashboard = (data?.stats || data || {}) as DashboardStats
      } catch {
        // ignore
      } finally {
        this.loading.dashboard = false
      }
    },

    async initialize() {
      await Promise.allSettled([
        this.fetchPermissions(),
        this.fetchRoles(),
        this.fetchMenu(),
        this.fetchDashboard(),
      ])
    },

    reset() {
      this.sidebarCollapsed = false
      this.activeMenu = ''
      this.tabs = []
      this.permissions = []
      this.roles = []
      this.menuItems = []
      this.dashboard = {}
      this.loading = { permissions: false, menu: false, dashboard: false }
    },
  },

  persist: {
    key: 'sunlake-admin-store',
    storage: window.localStorage,
    paths: ['sidebarCollapsed', 'activeMenu', 'tabs', 'permissions', 'roles', 'menuItems'],
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  } as any,
})